﻿using JshRCSWebApi.Infrastructure;
using JshRCSWebApi.Infrastructure.Domain.DTO.SysService;
using JshRCSWebApi.Infrastructure.Domain.VO.SysService;
using JshRCSWebApi.Service.SysService;
using JshRCSWebApi.SqlSugarDB.Model.jshrcs_initial;
using JshRCSWebApi.Util.Cache;
using JshRCSWebApi.Util.Cache.Redis;
using JshRCSWebApi.Util.DataAccess;
using JshRCSWebApi.Util.Json;
using Newtonsoft.Json;
using Org.BouncyCastle.Crypto.Parameters;
using ServiceStack;
using SqlSugar.Repository;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Text.Information;

namespace JshRCSWebApi.ServiceImpl.SysService
{
    public class UserServiceImpl : UserService
    {
        private readonly Repository<dynamic> _repository;

        public UserServiceImpl(Repository<dynamic> repository, MenuService menuService)
        {
            _repository = repository;
        }

        /// <summary>
        /// 用户登录
        /// </summary>
        /// <param name="AccountNum">账号</param>
        /// <param name="PassWord">密码</param>
        /// <param name="CardNum">卡号</param>
        /// <returns></returns>
        public async Task<ApiResult> Login(string UserName, string PassWord, string CardNum = "")
        {
            serviceuser suEntity = null;

            if (string.IsNullOrEmpty(CardNum))
            {
                suEntity = _repository.Select<serviceuser>().Where(w => w.suAccountNum == UserName).First();
                if (suEntity != null)
                {
                    string MD5Pwd = Md5Helper.EncryptString(suEntity.suCardNum + suEntity.suAccountNum + PassWord);
                    if (MD5Pwd != suEntity.suPwd)
                        return await Task.Run(() => ApiResult.Error($"很抱歉，您输入的密码不正确。"));
                }
            }
            else
                suEntity = _repository.Select<serviceuser>().Where(w => w.suCardNum == CardNum).First();

            if (suEntity != null)
            {

                //SaveCacheID(suEntity.ID);
                _repository.Add(new servicelog()
                {
                    CreateTime = DateTime.Now,
                    slContent = $"{suEntity.suName}登录系统成功。",
                    slIPAddress = WebService.GetIP(),
                    slElapsedTicks = 100,
                    CreateBy = suEntity.ID,
                    slTableName = "serviceuser",
                    slTitle = $"登录",
                    slType = "运行日志"
                });
                //令牌所承载的信息

                return await Task.Run(() => ApiResult.Success($"欢迎{suEntity.suName}登录本系统！", suEntity));
            }
            return await Task.Run(() => ApiResult.Error("很抱歉，登录失败，找不到您的账号！"));
        }

        /// <summary>
        /// 获取用户
        /// </summary>
        /// <param name="ID">id</param>
        /// <returns></returns>
        public async Task<ApiResult> GetUserInfo(long ID)
        {
            serviceuser suEntity = _repository.Select<serviceuser>().Where(w => w.ID == ID).First();
            if (suEntity != null)
            {
               var sRJur =  _repository.Select<servicerole>()
                                        .Where(sr => sr.ID == suEntity.suSRID)
                                        .First()
                                        .srJurisdiction;
                var totalSRJur = suEntity.suJurisdiction + "," + sRJur;
                var menuList = await GetUserAndRoleJur(totalSRJur);

                if ( menuList != null && menuList.Count() > 0)
                {
                    return await Task.Run(async () => ApiResult.Success("查询用户信息成功", new { Name = suEntity.suName, menuList = menuList }));
                }
            }
            return await Task.Run(async () => ApiResult.Error("查无用户或找不到用户菜单"));
        }

        /// <summary>
        /// 获取用户和角色共有的菜单权限
        /// </summary>
        /// <param name="strJur"></param>
        /// <returns></returns>
        public async Task<List<MenuSearchVO>> GetUserAndRoleJur(string strJur)
        {
            var jurList = strJur.Split(",").Select(j => long.Parse(j)).ToList();
            var menuList = _repository.SelectIn<servicemenu>("ID", jurList)
                             .Where(sm => sm.smParentID == 0)
                             .OrderBy(sm => sm.smSort)
                             .Select(sm => new MenuSearchVO()
                             {
                                 ID = sm.ID,
                                 title = JsonHelper.ToObj<Language>(sm.smTitle).zh,
                                 name = sm.smName,
                                 path = sm.smPath,
                                 component = sm.smComponent,
                                 redirect = sm.smRedirect,
                                 icon = sm.smIcon,
                                 meta = new meta()
                                 {
                                     en = JsonHelper.ToObj<Language>(sm.smTitle).en,
                                     zh = JsonHelper.ToObj<Language>(sm.smTitle).zh,
                                     icon = sm.smIcon,
                                     title = JsonHelper.ToObj<Language>(sm.smTitle).zh
                                 }
                             }).ToList();
            if (menuList.Count > 0)
            {
                menuList.ForEach(item =>
                {
                    var subMenuList = _repository.SelectList<servicemenu>()
                                  .Where(sm => sm.smParentID == item.ID &&jurList.Contains(sm.ID))
                                  .OrderBy(sm => sm.smSort)
                                  .Select(sm => new MenuSearchVO()
                                  {
                                      ID = sm.ID,
                                      title = JsonHelper.ToObj<Language>(sm.smTitle).zh,
                                      name = sm.smName,
                                      path = sm.smPath,
                                      component = sm.smComponent,
                                      redirect = sm.smRedirect,
                                      icon = sm.smIcon,
                                      meta = new meta()
                                      {
                                          en = JsonHelper.ToObj<Language>(sm.smTitle).en,
                                          zh = JsonHelper.ToObj<Language>(sm.smTitle).zh,
                                          icon = sm.smIcon,
                                          title = JsonHelper.ToObj<Language>(sm.smTitle).zh
                                      }
                                  }).ToList();
                    item.children = subMenuList;
                });
            }
            return await Task.Run(async () =>
            {
                return menuList.Count > 0 ? menuList : null;
            });
        }

        /// <summary>
        /// 修改用户
        /// </summary>
        /// <param name="suEntity">用户</param>
        /// <returns></returns>
        public async Task<ApiResult> UpdateUser(UserUpdateDTO userDTO,int UID)
        {
            var user = new serviceuser()
            {
                ID = userDTO.ID,
                suAccountNum = userDTO.suAccountNum,
                suCardNum = userDTO.suCardNum,
                suBriefIntroduction = userDTO.suBriefIntroduction,
                suName = userDTO.suName,
                suSex = userDTO.suSex,
                suPassed = userDTO.suPassed,
                suSDID = userDTO.suSDID,
                suSRID = userDTO.suSRID,
                ModifyBy = UID,
                ModifyTime = DateTime.Now
            };
            var count =  _repository.UpdateColumns(user, u => u.ID == userDTO.ID,
                new string[] { "suAccountNum", "suCardNum", "suBriefIntroduction", "suName", "suSex", "suPassed", "suSDID", "suSRID", "ModifyBy", "ModifyTime" });
            return count > 0 ? await Task.Run(() => ApiResult.Success("修改用户成功")) :
                 await Task.Run(() => ApiResult.Error("修改用户失败"));
        }
        /// <summary>
        /// 删除用户
        /// </summary>
        /// <param name="ID">用户编号</param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<ApiResult> DeleteUser(long ID) =>
       _repository.Context.Deleteable<serviceuser>().In(ID).ExecuteCommand() > 0 ?
                              await Task.Run(async () => ApiResult.Success("删除成功")) : await Task.Run(async () => ApiResult.Error("删除失败")); 

        /// <summary>
        /// 修改用户密码
        /// </summary>
        /// <returns></returns>
        public async Task<ApiResult> UpdateUserPWD(UserUpdatePwdDTO pwdDTO)
        {
            var userInfo = _repository.Select<serviceuser>().Where(u => u.ID == pwdDTO.ID).First();
            var enPwd = Md5Helper.EncryptString(userInfo.suCardNum + userInfo.suAccountNum + pwdDTO.PWD);
            return await Task.Run(() => {
                int count = _repository.UpdateColumns(new serviceuser() { suPwd = enPwd }, w => w.ID == pwdDTO.ID,new string[] { "suPwd" });
                return count > 0 ? ApiResult.Success("用户密码修改成功") : ApiResult.Error("找不到修改的用户");
            });
        }

        /// <summary>
        /// 获取用户列表
        /// </summary>
        /// <returns></returns>
        public async Task<dynamic> GetUserList(UserSearchDTO searchDTO)
        {
            var dInfo = _repository.Select<servicedepartment>()
                                     .Where(d => d.sdName == searchDTO.sdName)
                                      .First();
            long sdId = dInfo?.ID ?? 0;
            var rInfo = _repository.Select<servicerole>()
                         .Where(r => r.srName == searchDTO.srName)
                         .First();
            long srId = rInfo?.ID ?? 0;
            int total = 0;
            var userList = _repository.Context.Queryable<serviceuser>()
                            .WhereIF(sdId != 0, u => u.suSDID == sdId)
                            .WhereIF(srId != 0, u => u.suSRID == srId)
                            .WhereIF(!string.IsNullOrEmpty(searchDTO.suName), u => u.suName.Contains(searchDTO.suName))
                            .WhereIF(!string.IsNullOrEmpty(searchDTO.suAccountNum), u => u.suAccountNum.Contains(searchDTO.suAccountNum))
                            .WhereIF(!string.IsNullOrEmpty(searchDTO.suCardNum), u => u.suCardNum.Contains(searchDTO.suCardNum))
                            .ToPageList(searchDTO.pageNo, searchDTO.pageSize,ref total);
            var userInfoList = new List<UserInfoVO>();
             var dpList =   _repository.SelectList<servicedepartment>();
             var roleList = _repository.SelectList<servicerole>();
            userList.ForEach(user =>
            {
                string sdName = dpList.Where(d => user.suSDID == d.ID).First().sdName;
                string srName = roleList.Where(r => user.suSRID == r.ID).First().srName;
                string roleJs = roleList.Where(r => user.suSRID == r.ID).First().srJurisdiction;
                string Js = string.Empty;
                List<string> Jurs = new List<string>();
                if (!string.IsNullOrEmpty(user.suJurisdiction))
                {
                    Js = user.suJurisdiction + $",{roleJs}";
                    Jurs = Js.Split(',').Distinct().ToList();
                }
                else
                {
                    Jurs = roleJs.Split(',').ToList();
                }
                userInfoList.Add(new UserInfoVO()
                {
                    ID = user.ID,
                    suSDName = sdName,
                    suSDID = user.suSDID,
                    suSRName = srName,
                    suName = user.suName,
                    suSRID = user.suSRID,
                    suAccountNum = user.suAccountNum,
                    suCardNum = user.suCardNum,
                    suBriefIntroduction = user.suBriefIntroduction,
                    suControl = user.suControl,
                    suPassed = user.suPassed,
                    suSex = user.suSex,
                    suJurisdiction = String.Join(",",Jurs),
                    CreateTime = user.CreateTime

                });
            });
            return await Task.Run(async () => new { userList = userInfoList, total = total });
        }

        /// <summary>
        /// 通过ID获取用户信息
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<ApiResult> GetUserInfoByID(long id)
        {
            var user = _repository.Select<serviceuser>()
                                          .Where(u => u.ID == id)
                                           .First();
            if (user == null)
            {
                return await Task.Run(async () => ApiResult.Error("查询失败"));
            }
            else
            {
                user.suPwd = string.Empty;
                var sdName = _repository.Select<servicedepartment>().Where(d => user.suSDID == d.ID).First().sdName;
                var srName = _repository.Select<servicerole>().Where(r => user.suSRID == r.ID).First().srName;
                var userInfo = new UserInfoVO()
                {
                    ID = user.ID,
                    suSDName = sdName,
                    suSDID = user.suSDID,
                    suSRName = srName,
                    suSRID = user.suSRID,
                    suAccountNum = user.suAccountNum,
                    suCardNum = user.suCardNum,
                    suBriefIntroduction = user.suBriefIntroduction,
                    suControl = user.suControl,
                    suPassed = user.suPassed,
                    suSex = user.suSex,
                };
                return await Task.Run(async () => ApiResult.Success("查询成功", userInfo));
            }
        }

        /// <summary>
        /// 新增用户
        /// </summary>
        /// <param name="user"></param>
        /// <returns></returns>
        public async Task<ApiResult> AddUser(UserAddDTO userDTO,int UID)
        {
             var userInfo =  _repository.Select<serviceuser>()
                                .Where(u => u.suAccountNum == userDTO.suAccountNum)
                                .First();
            if (userInfo !=null)
            {
                return await Task.Run(async () => ApiResult.Error("该用户已存在"));
            }
            var enPassword = Md5Helper.EncryptString(userDTO.suCardNum + userDTO.suAccountNum + userDTO.suPwd) ;
            userDTO.suPwd = enPassword;
            var user = new serviceuser()
            {
                suAccountNum = userDTO.suAccountNum,
                suCardNum = userDTO.suCardNum,
                suBriefIntroduction= userDTO.suBriefIntroduction,
                suName = userDTO.suName,
                suSex = userDTO.suSex,
                suPwd = userDTO.suPwd,
                suPassed= userDTO.suPassed,
                suSDID = userDTO.suSDID,
                suSRID = userDTO.suSRID,
                CreateBy = UID,
                CreateTime = DateTime.Now,
            };
            if (_repository.Add<serviceuser>(user) > 0)
                return await Task.Run(async () => ApiResult.Success("新增成功"));
            else
            {
                return await Task.Run(async () => ApiResult.Error("新增失败"));
            }
        }

        /// <summary>
        /// 修改用户权限
        /// </summary>
        /// <param name="updateDto"></param>
        /// <param name="UID"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<ApiResult> UpdateUserJurisdiction(UserUpdateJurisdictionDTO updateDto, int UID)
        {
            int count = _repository.UpdateColumns(new serviceuser()
                                    {
                                        suJurisdiction = updateDto.StrJurisdiction,
                                        ModifyBy = UID,
                                        ModifyTime = DateTime.Now
                                    }, u => u.ID == updateDto.ID, new string[]
                                    {
                                        "suJurisdiction",
                                        "ModifyBy",
                                        "ModifyTime"
                                    });
            return await Task.Run(async () =>
            {
                return count > 0 ? ApiResult.Success("修改成功") : ApiResult.Error("修改失败");
            });
        }

        /// <summary>
        /// 获取用户和角色所有菜单权限
        /// </summary>
        /// <param name="UID"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<ApiResult> GetUserAndRoleAllJurisdiction(int UID)
        {
            serviceuser suEntity = _repository.Select<serviceuser>().Where(w => w.ID == UID).First();
            var sRJur = _repository.Select<servicerole>()
                                       .Where(sr => sr.ID == suEntity.suSRID)
                                       .First()
                                       .srJurisdiction;
            var totalSRJur = suEntity.suJurisdiction + "," + sRJur;
            var jurList = totalSRJur.Split(",").Select(j => long.Parse(j)).ToList();
            var menuList = _repository.SelectIn<servicemenu>("ID",jurList)
                                  .Where(sm => sm.smParentID == 0)
                                  .OrderBy(sm => sm.smSort)
                                  .Select(sm => new MenuSearchIDAndTitleVO()
                                  {
                                      ID = sm.ID,
                                      smTitle = sm.smTitle,
                                  }).ToList();
            if (menuList.Count > 0)
            {
                menuList.ForEach(item =>
                {
                    var subMenuList = _repository.SelectList<servicemenu>()
                                  .Where(sm => sm.smParentID == item.ID && jurList.Contains(sm.ID))
                                  .Select(sm => new MenuSearchIDAndTitleVO()
                                  {
                                      ID = sm.ID,
                                      smTitle = sm.smTitle
                                  }).ToList();
                    item.children = subMenuList;
                });
            }
            return await Task.Run(async () =>
            {
                return menuList.Count() > 0 ? ApiResult.Success("查询成功", menuList) : ApiResult.Error("查询失败");
            });
        }

        /// <summary>
        /// 用户退出
        /// </summary>
        /// <param name="UID"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<ApiResult> LogOut(int UID)
            => await Task.Run(async () =>
            {
                return RedisFn.fn_redis_remove_key($"user_{UID}") ? ApiResult.Success("退出成功") : ApiResult.Error("退出失败");
            });
    }
}
